<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;

class JdtMakeClassCommand extends Command
{
    protected $signature = 'make:Jdt {param} {--table=}';
    protected $description = '机动组 创建 控制器/模型/服务层/验证类/模型过滤 命令';
    protected static $controllerDir = 'Controllers/';
    protected static $modelDir = 'Models/';
    protected static $serviceDir = 'Services/';
    protected static $filterDir = 'Filters/';
    protected static $requestDir = 'Requests/';


    public $actionArr = [
        1 => '创建控制器',
        2 => '创建模型层',
        3 => '创建服务层',
        4 => '创建筛选层',
        5 => '创建验证层',
        6 => '创建列表插件',
    ];


    /**
     * FunctionName：创建控制器
     * Description：创建控制器
     * Author：lwl
     */
    public function 创建控制器()
    {
        $param = $this->argument('param');
        $controller = projectPath()['project_path'] . self::$controllerDir . $param . '.php';
        $namespace = trim(projectPath()['project'], '\\');
        if (file_exists($controller)) {
            $this->error("已经存在 {$param} 控制器");
            die();
        }
        $bool = $this->mkDoc($controller, $param, $namespace, "Controllers");
        if ($bool) {
            $this->info($controller . '文件创建成功');
            die();
        }
        $this->error($controller . '文件创建失败');
        die();
    }

    /**
     * FunctionName：创建模型层
     * Description：创建模型层
     * Author：lwl
     */
    public function 创建模型层()
    {
        $param = $this->argument('param');
        $table = $this->option('table');
        $model = projectPath()['project_path'] . self::$modelDir . $param . '.php';
        $namespace = trim(projectPath()['project'], '\\');
        if (file_exists($model)) {
            $this->error("已经存在 {$param} 模型");
            die();
        }
        $bool = $this->mkDoc($model, $param, $namespace, "Models",$table);
        if ($bool) {
            $this->info($model . '文件创建成功');
            die();
        }
        $this->error($model . '文件创建失败');
        die();
    }

    /**
     * FunctionName：创建服务层
     * Description：创建服务层
     * Author：lwl
     */
    public function 创建服务层()
    {
        $param = $this->argument('param');
        $model = projectPath()['project_path'] . self::$serviceDir . $param . '.php';
        $namespace = trim(projectPath()['project'], '\\');
        if (file_exists($model)) {
            $this->error("已经存在 {$param} 服务层");
            die();
        }
        $bool = $this->mkDoc($model, $param, $namespace, "Services");
        if ($bool) {
            $this->info($model . '文件创建成功');
            die();
        }
        $this->error($model . '文件创建失败');
        die();
    }

    public function 创建列表插件()
    {
        $param = $this->argument('param');
        $model = projectPath()['project_path'] . self::$serviceDir . $param . '.php';
        $namespace = trim(projectPath()['project'], '\\');
        if (file_exists($model)) {
            $this->error("已经存在 {$param} 服务层");
            die();
        }
        $bool = $this->mkDoc($model, $param, $namespace, 'ListServices');
        if ($bool) {
            $this->info($model . '文件创建成功');
            die();
        }
        $this->error($model . '文件创建失败');
        die();
    }



    public function 创建验证层()
    {
        $param = $this->argument('param');
        $model = projectPath()['project_path'] . self::$requestDir . $param . '.php';
        $namespace = trim(projectPath()['project'], '\\');
        if (file_exists($model)) {
            $this->error("已经存在 {$param} 验证类");
            die();
        }
        $bool = $this->mkDoc($model, $param, $namespace, 'Requests');
        if ($bool) {
            $this->info($model . '文件创建成功');
            die();
        }
        $this->error($model . '文件创建失败');
        die();
    }

    public function 创建筛选层()
    {
        $param = $this->argument('param');
        $model = projectPath()['project_path'] . self::$filterDir . $param . '.php';
        $namespace = trim(projectPath()['project'], '\\');
        if (file_exists($model)) {
            $this->error("已经存在 {$param} 模型过滤类");
            die();
        }
        $bool = $this->mkDoc($model, $param, $namespace, 'Filters');
        if ($bool) {
            $this->info($model . '文件创建成功');
            die();
        }
        $this->error($model . '文件创建失败');
        die();
    }

    /**
     * FunctionName：handle
     * Description：
     * Author：lwl
     * @return bool
     */
    public function handle()
    {
        $param = $this->argument('param');
        //$table = $this->option('table');
        $this->line($param);
        $this->initConsole();
        return true;
    }

    /**
     * FunctionName：initConsole
     * Description：自选
     * Author：lwl
     */
    public function initConsole()
    {
        $answer = $this->choice('请选择要操作的数字', $this->actionArr);
        if (array_key_exists(intval($answer), $this->actionArr) || in_array($answer, $this->actionArr)) {
            $this->info('正在执行：' . $answer . PHP_EOL);
            $this->$answer();
        }
    }

    /**
     * FunctionName：mkDoc
     * Description：创建文件
     * Author：lwl
     * @param $filename :文件
     * @param $param :类名
     * @param $namespace :命名空间
     * @param int $type :1:控制器，2:模型，3：服务
     * @return bool
     */
    protected function mkDoc($filename, $param, $namespace, $type = 'Controllers',$table = '')
    {
        $class = $param;
        $paramArray = explode('/', $this->argument('param'));
        if (count($paramArray) > 1) {
            $class = array_pop($paramArray);
            $dirPath = projectPath()['project_path'] . $type . '/' . implode('/', $paramArray);
            @mkdir($dirPath, 0777);
            $namespacePath = $type . '\\' . implode('\\', $paramArray);
            $namespace = $namespace . '\\' . $namespacePath;
        } else {
            $namespace = $type == 'ListServices' ? $namespace . '\\' .'Services' : $namespace . '\\' . $type;
        }
        $res = fopen($filename, 'w');
        switch ($type) {
            case "Controllers":
                $content = self::controllerContent($class, $namespace);
                break;
            case "Models":
                $content = self::modelContent($class, $namespace,$table);
                break;
            case 'Filters':
                $content = self::FilterContent($class, $namespace);
                break;
            case 'Requests':
                $content = self::RequestContent($class, $namespace);
                break;
            case 'ListServices':
                $content = self::ListContent($class, $namespace);
                break;
            default:
                $content = self::serviceContent($class, $namespace);
                break;
        }
        fputs($res, $content);
        fclose($res);
        return true;
    }

    /**
     * FunctionName：controllerContent
     * Description：控制器内容
     * Author：lwl
     * @param $class
     * @param $namespace
     * @return string
     */
    protected static function controllerContent($class, $namespace)
    {
        $temp = explode('\\', $namespace);
        $classTemp = str_replace('Controller', '', $class);
        $classService = $classTemp . 'Service';
        $currentTemp = current($temp);
        $date = date('Y/m/d H:i:s');
        $request = '$request';
        $service = '$service';
        $thisRequest = '$this->request';
        $thisService = '$this->service';
        $servicePath = "use {$currentTemp}\Services\\$classService";
        $serviceList = 'return (new '.$classTemp.'ListService())->make($this->request->input())->get()';
        $classListService = $classTemp . 'ListService';
        $serviceListPath = "use {$currentTemp}\Services\\$classListService";
        $switch = 'return $this->service->switch($this->request->input("id",0))';
        $remove = 'return $this->service->remove($this->request->input("id",0))';
        $getAll = 'return $this->service->getAll()';
        $edit = 'return $this->service->edit($this->request->input())';
        $show = 'return $this->service->show($this->request->input("id",0))';
        $store = 'return $this->service->store($this->request->input())';

        return <<<EOF
<?php
/**
 * Copyright (C), 2021-2021, Shall Buy Life info. Co., Ltd.
 * FileName:$class.php
 * Description:
 *
 * @author:
 * @Create Date    $date
 * @Update Date    $date
 * @version v1.0
 */

namespace $namespace;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
$servicePath;
$serviceListPath;

class $class extends Controller
{
    /**
     * @param Request $request
     * @param $classService $service
     */
    protected $request;
    protected $service;

    /**
     * @param Request $request
     * @param $classService $service
     */
    public function __construct(Request $request,$classService $service)
    {
        $thisRequest = $request;
        $thisService = $service;
    }

    /**
     * FunctionName：store
     * Description：创建
     * Author：lwl
     * @return null
     */
    public function store()
    {
        $store;
    }

    /**
     * FunctionName：list
     * Description：列表
     * Author：lwl
     * @return null
     */
    public function list()
    {
        $serviceList;
    }

    /**
     * FunctionName：show
     * Description：详情
     * Author：lwl
     * @return null
     */
    public function show()
    {
        $show;
    }

    /**
     * FunctionName：edit
     * Description：更新
     * Author：lwl
     * @return null
     */
    public function edit()
    {
        $edit;
    }

    /**
     * FunctionName：getAll
     * Description：全部数据
     * Author：lwl
     * @return null
     */
    public function getAll()
    {
        $getAll;
    }

    /**
     * FunctionName：remove
     * Description：删除
     * Author：lwl
     * @return null
     */
    public function remove()
    {
        $remove;
    }

    /**
     * FunctionName：switch
     * Description：开启/关闭
     * Author：lwl
     * @return null
     */
    public function switch()
    {
        $switch;
    }

}
EOF;
    }


    /**
     * FunctionName：modelContent
     * Description：模型内容
     * Author：lwl
     * @param $class
     * @param $namespace
     * @return string
     */
    public static function modelContent($class, $namespace,$sqlTable)
    {
        $date = date('Y/m/d H:i:s');
        $table = '$table';
        $fillable = '$fillable';
        $fillableFields = self::modelFillable($sqlTable);


        $query = '$query';
        $filters = '$filters';
        $apply = 'return $filters->apply($query)';
        $temp = explode('\\', $namespace);
        $currentTemp = current($temp);
        $attributes = '$attributes';
        $this_ = '$this';
        return <<<EOF
<?php
/**
 * Copyright (C), 2016-2018, Shall Buy Life info. Co., Ltd.
 * FileName:$class.php
 * Description: 说明
 *
 * @author
 * @Create Date    $date
 * @Update Date    $date
 * @version v1.0
 */

namespace $namespace;

use $currentTemp\Filters\QueryFilter;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class $class extends BasicModel
{
    use SoftDeletes;
    protected $table = "$sqlTable";

    protected $fillable = $fillableFields

    public function __construct(array $attributes = [])
    {
        $this_->_name = $this_ ;
        parent::__construct($attributes);
    }

    /**
     * FunctionName：scopeFilter
     * Description：
     * Author：lwl
     * @param $query
     * @param QueryFilter $filters
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function scopeFilter($query, QueryFilter $filters)
    {
        $apply;
    }
}
EOF;
    }


    private static function modelFillable($table):string
    {
        $sql = "SHOW FULL COLUMNS FROM `$table`";
        $result = DB::select($sql);

        $fields = '[';
        foreach ($result as $value){
            $fields .= '"'.$value->Field.'"'  .',' .PHP_EOL;
        }
        $fields = $fields.'];';
        return $fields;
    }

    /**
     * FunctionName：serviceContent
     * Description：服务内容
     * Author：lwl
     * @param $class
     * @param $namespace
     * @return string
     */
    public static function serviceContent($class, $namespace)
    {
        $params = '$params';
        $final = 'final';
        $declare = 'declare(strict_types=1)';
        $id = '$id';
        $date = date("Y/m/d H:i:s");
        $paramsId = '$params["id"]';
        $temp = explode('\\', $namespace);
        $currentTemp = current($temp);
        $tempModel = str_replace('Service', '', $class);
        $modelPath = "use {$currentTemp}\Models\\$tempModel";
        $model = "$tempModel";
        $result = '$result';
        $returnCode = "use $currentTemp\Constants\CodeMessageConstant";
        $updateStr = "$result".'->'.'update($params)';
        $delStr = "$result".'->'.'delete($id)';
        $switchStr = "$result".'->'.'update($result->status == 1 ? CodeMessageConstant::CLOSE : CodeMessageConstant::OPEN)';
        return <<<EOF
<?php
/**
 * Copyright (C), 2016-2018, Shall Buy Life info. Co., Ltd.
 * FileName:$class.php
 * Description: 说明
 *
 * @author lwl
 * @Create Date $date
 * @Update Date $date
 * @version v1.0
 */
$declare;
namespace $namespace;
$modelPath;
$returnCode;

$final class $class
{
    /**
     * FunctionName：store
     * Description：创建
     * Author：lwl
     * @param array $params
     * @return null
     */
    public function store(array $params)
    {
        if (!$model::query()->create($params)) {
            return fail(CodeMessageConstant::ERROR_OPERATION_FAIL);
        }
        return null;
    }

    /**
     * FunctionName：list
     * Description：列表
     * Author：lwl
     * @return null
     */
    public function list()
    {
        return;
    }

    /**
     * FunctionName：show
     * Description：详情
     * Author：lwl
     * @param int $id
     * @return null
     */
    public function show(int $id)
    {
        if (!$result = $model::query()->whereKey($id)->first()) {
            return fail(CodeMessageConstant::ERROR_DATA_NOT_EXISTS);
        }
        return $result;
    }

    /**
     * FunctionName：edit
     * Description：更新
     * Author：lwl
     * @param array $params
     * @return null
     */
    public function edit(array $params)
    {
       if (!$result = $model::query()->whereKey($paramsId)->first()) {
            return fail(CodeMessageConstant::ERROR_DATA_NOT_EXISTS);
        }
        if (!$updateStr) {
            return fail(CodeMessageConstant::ERROR_OPERATION_FAIL);
        }

        return null;
    }

    /**
     * FunctionName：getAll
     * Description：全部数据
     * Author：lwl
     * @return null
     */
    public function getAll()
    {
        return $model::query()->orderByDesc('created_at')->get();
    }

    /**
     * FunctionName：remove
     * Description：删除
     * Author：lwl
     * @param int $id
     * @return null
     */
    public function remove(int $id)
    {
        if (!$result = $model::query()->whereKey($id)->first()) {
            return fail(CodeMessageConstant::ERROR_DATA_NOT_EXISTS);
        }

        if (!$delStr) {
             return fail(CodeMessageConstant::ERROR_OPERATION_FAIL);
        }

        return null;
    }

    /**
     * FunctionName：switch
     * Description：开启/关闭
     * Author：lwl
     * @param int $id
     * @return null
     */
    public function switch(int $id)
    {
        if (!$result = $model::query()->whereKey($id)->first()) {
            return fail(CodeMessageConstant::ERROR_DATA_NOT_EXISTS);
        }

        if (!$switchStr) {
             return fail(CodeMessageConstant::ERROR_OPERATION_FAIL);
        }

        return null;
    }
}
EOF;
    }


    /**
     * FunctionName：serviceContent
     * Description：模型过滤
     * Author：lwl
     * @param $class
     * @param $namespace
     * @return string
     */
    public static function FilterContent($class, $namespace)
    {
        /*$date = date('Y/m/d H:i:s');
        $table = '$table';
        $fillable = '$fillable';*/
        return <<<EOF
<?php
/**
 * Copyright (C), 2016-2018, Shall Buy Life info. Co., Ltd.
 * FileName:$class.php
 * Description: 模型过滤
 *
 * @author
 * @Create Date
 * @Update Date
 * @version v1.0
 */

namespace $namespace;

class $class extends QueryFilter
{

}
EOF;
    }


    public static function RequestContent($class, $namespace)
    {
        $id = '$id = request()->input("id",0)';
        $_id = '$id';
        $scenes = '$scenes';
        $date = date('Y/m/d H:i:s');
        return <<<EOF
<?php
/**
 * Copyright (C), 2021-2021, Shall Buy Life info. Co., Ltd.
 * FileName: $class.php
 * Description:
 *
 * @author lwl
 * @Create Date    $date
 * @Update Date    $date
 * @version v1.0
 */

namespace $namespace;

class $class extends BaseRequest
{

    /**
     * 验证场景器
     * @var \string[][]
     */
    public $scenes = [
        'store' => ['title'], //场景验证器名称 和 控制器方法一致
        'edit' => ['title', 'id'],//场景验证器名称 和 控制器方法一致
    ];

    /**
     * FunctionName：authorize
     * Description：鉴权
     * Author：lwl
     * @return bool
     */
    public function authorize(): bool
    {
        return true;
    }

    /**
     * FunctionName：rules
     * Description：验证规则
     * Author：lwl
     * @return string[]
     */
    public function rules(): array
    {
        return self::baseRules();

    }

    /**
     * FunctionName：baseRules
     * Description：
     * Author：lwl
     * @return string[]
     */
    private static function baseRules():array
    {
        $id;
        return [
            'title' => 'required',
            'unique_code' => "required|unique:decoration_workflows,unique_code,$_id,id,deleted_at,NULL"//decoration_workflows 表名，unique_code字段
        ];
    }

    /**
     * FunctionName：attributes
     * Description：
     * Author：lwl
     * @return string[]
     */
    public function attributes():array
    {
        return [
            'title' => '名称',
        ];
    }
}
EOF;
    }


    public static function listContent($class, $namespace)
    {
        $microConstant = '$microConstant';
        $micro = '$this->micro = $microConstant';
        $businesId = '$businesId';
        $key = '$key';
        $root = '$root';
        $display = '$display';
        $joins = '$joins';
        $headers = '$headers';
        $conditions = '$conditions';
        $orderBy = '$orderBy';
        $custom = '$custom';
        $query = '$query';
        $bool = '$bool';
        $result = '$result';
        $action = '$this->action';
        $final = 'final';
        $declare = 'declare(strict_types=1)';
        $temp = explode('\\', $namespace);
        $currentTemp = current($temp);
        $tempModel = str_replace('ListService', '', $class);
        $modelPath = "use {$currentTemp}\Models\\$tempModel";
        $model = "$tempModel";
        $date = date('Y/m/d H:i:s');
        return <<<EOF
<?php
/**
 * Copyright (C), 2016-2018, Shall Buy Life info. Co., Ltd.
 * FileName: $class.php
 * Description: 说明
 *
 * @author lwl
 * @Create Date    $date
 * @Update Date    $date
 * @version v1.0
 */
$declare;
namespace $namespace;

use $currentTemp\Constants\MicroConstant;
use YiluTech\ComplexSearch\ComplexSearch;
$modelPath;

$final class $class extends ComplexSearch
{
    public function __construct(MicroConstant $microConstant){
        $micro;
    }

    public $businesId;   //可访问的业务权限

    public $key;

    public $root = $model::class;  //模型名称

    protected $display = 'simple';    //选择搜索框显示类型

    protected $joins = [];

    protected $headers = [
        ['value' => 'id', 'label' => '课程id'],
        ['value' => 'title', 'label' => '课程名称'],
        ['value' => 'image', 'label' => '图片或封面'],

    ];

    protected $conditions = [
        'id' => [
            'ctype' => 'input',
            'display' => true,
            'label' => 'ID',
        ],
        'title' => [
            'ctype' => 'input',
            'display' => true,
            'label' => '名称',
            'operator' => 'like',//模糊查询
        ],

        'location' => [
            'label' => '业务',
            'ctype' => 'cascade',
            'url' => 'school/staff/business/school/children/list',
            'key' => 'id',
            'labelField' => 'title',
            'valueField' => 'id',
            'options' => [
                [
                    'key' => 'business_id',
                    'placeholder' => '所属业务'
                ]
            ],
            'custom' => true
        ],
        'lecturer_type' => [
            'ctype' => 'select',
            'display' => true,
            'options' => [
                ['label' => '普通讲师', 'value' => 1],
                ['label' => '专业讲师', 'value' => 2],
            ],
            'label' => '讲师类型',
            'custom' => true//不进行where 查询

        ],
    ];



    protected $orderBy = 'created_at desc';  //排序

    /**
     * FunctionName：getConditions
     * Description：拼接搜索条件
     * Author：lwl
     * @param bool $custom
     * @return array
     */
    public function getConditions($custom = false)
    {
        return parent::getConditions($custom);
    }

    /**
     * FunctionName：addWheres
     * Description：
     * @param $query
     * @param null $conditions
     * @param string $bool
     * @return mixed
     * @throws \ShallBuy\LaravelBase\Common\Exception\Exceptions\BusinessException
     * @author lwl
     * @date 2021-08-18 1:15 下午
     */
    public function addWheres($query, $conditions = null, $bool = 'and')
    {

        return parent::addWheres($query, $conditions, $bool);
    }

    /**
     * FunctionName：query
     * Description：
     * @return \Illuminate\Database\Eloquent\Builder
     * @throws \Exception
     * @author lwl
     * @date 2021-08-16 16:01 下午
     */
    public function query()
    {

        $query = parent::query();

        return $query;
    }

    /**
     * FunctionName：get
     * Description：拼接返回数据
     * lwl
     * @return |null
     */
    public function get()
    {
        $result = parent::get();
        if($action === 'query') {
            //数据处理
        }
        return $result;
    }
}

EOF;

    }

}
